package com.play.ballen.home.task

import com.play.ballen.config.BallenConfig
import com.play.ballen.home.entity.PlayCountInfo
import com.yuven.appframework.network.RxSchedulerHelper
import com.yuven.appframework.util.DateFormat
import com.yuven.baselib.utils.Logger
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit

object TaskUtil {

    private var playCountInfo: PlayCountInfo? = null
    private var mStepCount = 0  //已走步数
    private var mStepCountLastUpdate = 0  //上次通知栏更新的步数
    private var mLeftCount = 0  //剩余步数
    private var mDisposed: Disposable? = null

    //步伐通知栏进度更新
    var stepNotificationUpdateCallBack: ((stepCount: Int) -> Unit)? = null

    //步伐改变
    var stepChangeCallBack: ((leftCount: Int) -> Unit)? = null

    //时间改变
    var timeChangeCallBack: ((format: String) -> Unit)? = null

    //完成回调
    var onCompleteCallBack: ((type: Int) -> Unit)? = null  //type=0步数走完 type=1时间走完 type=2手动结束
    const val COMPLETE_BY_STEP = 0    //步数
    const val COMPLETE_BY_TIME = 1    //时间
    const val COMPLETE_BY_MANUAL = 2    //手动

    fun setPlayCountInfo(info: PlayCountInfo) {
        Logger.i("TaskUtil.setPlayCountInfo info = $info")
        playCountInfo = info
        if (mStepCount == 0) {      //如果已走步数不为0的话就不覆盖本地已走的步数
            mStepCount = info.num   //已经走了的步数
            mStepCountLastUpdate = info.num //默认取上一次已上传的步数
        }

        stopTime()
        startTime(info.time)
    }

    fun stepCountIncrement(step: Int) {
        if (playCountInfo == null) {
            Logger.i("TaskUtil.stepCountIncrement playCountInfo==null")
            return
        }

        mStepCount += step
        Logger.i("TaskUtil.stepCountIncrement mStepCount = $mStepCount")

        mLeftCount = if (playCountInfo!!.task_count - mStepCount > 0) {
            playCountInfo!!.task_count - mStepCount
        } else {
            0
        }
        stepChangeCallBack?.invoke(mLeftCount)

        if (mStepCount == 0 || mStepCount - mStepCountLastUpdate >= BallenConfig.TASK_UPDATE_STEP_INTERVAL) {  //每隔10步 更新一次
            stepNotificationUpdateCallBack?.invoke(mStepCount)
            mStepCountLastUpdate = mStepCount
        }
    }

    private fun startTime(sum: Long) {
        Logger.i("TaskUtil.startTime sum = $sum")

        mDisposed = Observable.interval(0, 1, TimeUnit.SECONDS)
            .take(sum + 1)
            .map {
                val value = sum - it
                DateFormat.secToDayTime2(value)
            }
            .compose(RxSchedulerHelper.io_main())
            .subscribe({
                timeChangeCallBack?.invoke(it)
            }, { e ->
                e.printStackTrace()
            }, {
                complete(COMPLETE_BY_TIME)
            })
    }

    fun complete(type: Int) {
        Logger.i("TaskUtil.complete type = $type")

        resetConstant()
        timeChangeCallBack?.invoke("00:00:00")

        onCompleteCallBack?.invoke(type)
    }

    fun getStepCount(): Int {
        return mStepCount
    }

    fun getLeftCount(): Int {
        return mLeftCount
    }

    fun getTaskCount(): Int {
        return playCountInfo?.task_count ?: 0
    }

    fun getPlayCountInfo(): PlayCountInfo? {
        return playCountInfo
    }

    private fun resetConstant() {
        Logger.i("TaskUtil.resetConstant")

        playCountInfo = null
        mStepCount = 0
        mStepCountLastUpdate = 0
        mLeftCount = 0
    }

    fun resetStepCount() {
        Logger.i("TaskUtil.resetStepCount")
        mStepCount = 0
        mStepCountLastUpdate = 0
        stepCountIncrement(0)
    }

    private fun stopTime() {
        Logger.i("TaskUtil.stopTime")

        mDisposed?.let {
            if (!it.isDisposed) {
                it.dispose()
            }
        }
    }

    fun releaseAll() {
        Logger.i("TaskUtil.releaseAll")

        resetConstant()
        stopTime()

        stepNotificationUpdateCallBack = null
        stepChangeCallBack = null
        timeChangeCallBack = null
        onCompleteCallBack = null
    }

}